package com.unlcn.erp.hyc.interfaces.backend.service;


import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.unlcn.erp.hyc.interfaces.backend.bo.HYCWayBillDB;
import com.unlcn.erp.hyc.interfaces.backend.bo.HYCWayBillDetailDB;
import com.unlcn.erp.hyc.interfaces.backend.bo.OrderCodesDB;
import com.unlcn.erp.hyc.interfaces.backend.enums.CallHYCUrlTypeEnum;
import com.unlcn.erp.hyc.interfaces.base.mapper.*;
import com.unlcn.erp.hyc.interfaces.base.model.*;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * 获取
 * Created by zhiche024 on 2017/9/6.
 */
@Service
public class CallWayBillByHYCServiceImpl implements CallWayBillByHYCService{

    private static final Logger LOGGER = LoggerFactory.getLogger(CallWayBillByHYCServiceImpl.class);

    private static final String WAYBILL = "WAYBILL" ,GETWAYBILLDETAIL = "GETWAYBILLDETAIL";
    @Autowired
    private CallHYCUrlReceiveService callHYCUrlReceiveService;
    @Autowired
    private CheckIntermediateService checkIntermediateService;
    @Autowired
    private CallOrderByHYCService callOrderByHYCService;
    @Autowired
    private HycwaybillMapper hycwaybillMapper;
    @Autowired
    private HycwaybilldetailMapper hycwaybilldetailMapper;
    @Autowired
    private SoshipheadMapper soshipheadMapper;
    @Autowired
    private SoshiplineMapper soshiplineMapper;
    @Autowired
    private SoorderMapper soorderMapper;
    @Autowired
    private HycExceptionMsgMapper hycExceptionMsgMapper;
    @Autowired
    private SocustomershipMapper socustomershipMapper;
    @Autowired
    private SocustshiporderMapper socustshiporderMapper;
    @Autowired
    private HycwaybilllistMapper hycwaybilllistMapper;
    @Autowired
    private HycorderMapper hycorderMapper;


    @Override
    public void getWayBillCodes() throws Exception{
        //调用接口获取运单号列表；
        String data = callHYCUrlReceiveService.callHYCUrlReceive(WAYBILL, null);
        //将接口返回的数据进行拆分；
        List<OrderCodesDB> OrderCodes = JSONObject.parseArray(data,OrderCodesDB.class);
        if(CollectionUtils.isNotEmpty(OrderCodes)){
            for(int i = 0; i < OrderCodes.size() ; i++ ){
                OrderCodesDB wayBillCode = OrderCodes.get(i);
                //获取订单的详细信息
                this.saveWayBillDetails(wayBillCode.getCode());
            }
        }
    }

    /**
     * 保存运单
     * @param wayBillDetail
     * @throws Exception
     */
    public void saveWayBillDetails(String wayBillDetail) throws Exception{

        HYCWayBillDB db = null;
        try{
            //根据订单号获取订单详细信息
            String data = callHYCUrlReceiveService.callHYCUrlReceive(GETWAYBILLDETAIL,wayBillDetail);
            db = JSONObject.parseObject(data, HYCWayBillDB.class);

            //将运单信息存入到中间表中
            this.saveWayBillByHYC(db);

            LOGGER.info(wayBillDetail+"该运单的保存成功！");
        }catch (Exception e){
            HycExceptionMsg msg = new HycExceptionMsg();
            msg.setExceptionMsg(e.toString());
            msg.setExceptionData(wayBillDetail);
            msg.setExceptionType(CallHYCUrlTypeEnum.HYC_WAYBILLDETAILS.getValue());
            hycExceptionMsgMapper.saveMsgByHYC(msg);
            LOGGER.error("运单保存出错:"+wayBillDetail+"异常信息："+e.toString());
            throw e;
        }
    }

    //将数据存入到运单表中
    public void saveWayBillByHYC(HYCWayBillDB db) throws Exception{

        //存入到运单中间表
        Hycwaybill hycwaybill = new Hycwaybill();
        BeanUtils.copyProperties(db,hycwaybill);

        //判断是否存在,如果不存在则添加
        HycwaybillExample example = new HycwaybillExample();
        example.createCriteria().andWaybillcodeEqualTo(hycwaybill.getWaybillcode());
        int intCount = hycwaybillMapper.countByExample(example);
        if(intCount <= 0 ){
            hycwaybillMapper.insertWayBillByHYC(hycwaybill);
        }
        else{
            hycwaybillMapper.updateByExampleSelective(hycwaybill,example);
        }

        //判断中间表数据是否存在
        Smcitymap startCity = checkIntermediateService.judgeCityMap(db.getDepartcitycode(),db.getDepartcityname(),db.getWaybillcode());
        Smcitymap endCity = checkIntermediateService.judgeCityMap(db.getReceiptcitycode(),db.getReceiptcityname(),db.getWaybillcode());

        //检查分供方数据
        Long shipno = checkIntermediateService.judgeShipMap(String.valueOf(db.getCarrierid()),db.getCarriername());

        //存入到运单明细中间表
        List<HYCWayBillDetailDB> wayBillDetailDBs =  JSONObject.parseArray(db.getServiceorderlist(),HYCWayBillDetailDB.class);

        //将数据保存到soshiphead中
        Boolean isZLShip = false;

        if("中联物流自有车队".equals(db.getCarriername()) || db.getCarrierid() == 151){
            isZLShip = true;
        }
        Long soshipheadId = null ;
        if(!isZLShip){
            soshipheadId = this.saveWayBillToSoshipHead(db,shipno);
        }

        //List<HYCWayBillDetailDB> wayBillDetailDBs = db.getServiceorderlist();

        //SOCUSTOMERSHIP 新增客户运单号
        // 对该指令的客户运单号进行分类
        Map<String,Long> map = this.getcustshipSize(db,wayBillDetailDBs);

        for(int i = 0; i < wayBillDetailDBs.size(); i++){
            HYCWayBillDetailDB detailDB = wayBillDetailDBs.get(i);

            String vcCustOrderNo= soorderMapper.getVcustomOrderNo(detailDB.getOrdercode());
            if(StringUtils.isEmpty(vcCustOrderNo)){
                vcCustOrderNo = callOrderByHYCService.getCustomerOrderCode(detailDB.getOrdercode());
            }

            Long iCustShipId = map.get(vcCustOrderNo);
            Hycwaybilldetail hycwaybilldetail = new Hycwaybilldetail();
            BeanUtils.copyProperties(detailDB,hycwaybilldetail);

            //判断车型是否存在中间表
            checkIntermediateService.judgeModersMap(hycwaybilldetail.getVehicleid(),hycwaybilldetail.getVehiclename(),iCustShipId);

            HycwaybilldetailExample detailExample = new HycwaybilldetailExample();
            detailExample.createCriteria().andWaybilldetailidEqualTo(hycwaybilldetail.getWaybilldetailid());
            List<Hycwaybilldetail> listWDetails = hycwaybilldetailMapper.selectByExample(detailExample);

            //保存运单明细中间表
            if(CollectionUtils.isEmpty(listWDetails)){
                hycwaybilldetailMapper.insertWayBillDetailByHYC(hycwaybilldetail);
            }
            else{
                hycwaybilldetailMapper.updateByExampleSelective(hycwaybilldetail,detailExample);
            }

            //如果是中联承运
            if(isZLShip){
                //对订单进行拆分
                Long iorderId = soorderMapper.getIlineidByOrderNo(hycwaybilldetail.getOrdercode());
                if(iorderId == null || "".equals(iorderId)){
                    LOGGER.error("未找到对应的订单"+hycwaybilldetail.getOrdercode());
                    callOrderByHYCService.getOrderDetails(hycwaybilldetail.getOrdercode());
                    iorderId = soorderMapper.getIlineidByOrderNo(hycwaybilldetail.getOrdercode());
                }
                this.splitSoorderByShip(db,startCity,endCity,hycwaybilldetail,iorderId);
            }else{
                //将详细信息保存到soshipline中
                if(soshipheadId == null){
                    LOGGER.error("未找到对应的运单主键："+hycwaybilldetail.getOrdercode());
                }
                this.saveWayBillToSoshipLine(db,startCity,endCity,soshipheadId,hycwaybilldetail,wayBillDetailDBs.size(),iCustShipId);
            }
        }
    }

    /**
     *  得到客户运单号
     * @param db
     * @param wayBillDetailDBs
     * @return
     * @throws Exception
     */
    private Map<String,Long> getcustshipSize(HYCWayBillDB db,List<HYCWayBillDetailDB> wayBillDetailDBs) throws Exception{
        Map<String,Integer> map = Maps.newHashMap();
        Map<String,Long> returnMap = Maps.newHashMap();
        List<String> list = new ArrayList<>();

        for(HYCWayBillDetailDB detaildb: wayBillDetailDBs){
            String vcCustOrderNo= soorderMapper.getVcustomOrderNo(detaildb.getOrdercode());
            if(StringUtils.isEmpty(vcCustOrderNo)){
                vcCustOrderNo = callOrderByHYCService.getCustomerOrderCode(detaildb.getOrdercode());
            }
            //如果不存在
            if(!map.containsKey(vcCustOrderNo)){
                HycorderExample example = new HycorderExample();
                example.createCriteria().andCustomerordercodeEqualTo(vcCustOrderNo);
                int intCount =hycorderMapper.countByExample(example);
                map.put(vcCustOrderNo,intCount);
                list.add(vcCustOrderNo);
            }
        }
        for(int i = 0; i < list.size(); i++){
            Long iCustShipId = this.saveSoCustomerShip(db,list.get(i),map.get(list.get(i)));
            returnMap.put(list.get(i),iCustShipId);
        }
        return returnMap;
    }

    /**
     * 存储调度指令头信息
     * @param db
     * @param shipno
     * @return
     * @throws Exception
     */
    private Long saveWayBillToSoshipHead(HYCWayBillDB db,Long shipno) throws Exception{

        Soshiphead soshiphead = new Soshiphead();

        SoshipheadExample example = new SoshipheadExample();
        example.createCriteria().andVcshipnoEqualTo(db.getWaybillcode());
        List<Soshiphead> soshipheads = soshipheadMapper.selectByExample(example);

        //获取司机的id
        Long driverId = checkIntermediateService.judgeDriverMap(db.getCarriername());
        //获取车辆的ID
        Long vehicleId = checkIntermediateService.judgeVehicleMap(db.getCarnumber(),shipno,driverId);

        //如果不存在则添加
        if(CollectionUtils.isEmpty(soshipheads)){
            //获取当前soshiphead主键值
            Long ilineid = soshipheadMapper.getShipHeadId();
            soshiphead.setIlineid(ilineid);
            soshiphead.setVcshipno(String.valueOf(db.getWaybillcode()));
            soshiphead.setDtdate(db.getCreatetime());
            soshiphead.setIvehicleid(vehicleId);
            soshiphead.setVcmemo(db.getComment());
            soshiphead.setIfleetid(shipno);
            soshiphead.setIfleetid2(shipno);
            soshiphead.setVclicense(db.getCarnumber());
            soshiphead.setIdriverid(driverId);
            soshiphead.setIarriveid(1l);
            soshiphead.setVcarriveuserno("hyc");
            soshiphead.setDtarrive(db.getCreatetime());
            soshipheadMapper.saveShipHeadByHYC(soshiphead);
        }
        else{
            //存在则更新
            soshiphead = soshipheads.get(0);
            soshiphead.setDtdate(db.getCreatetime());
            soshiphead.setIvehicleid(vehicleId);
            soshiphead.setVcmemo(db.getComment());
            soshiphead.setIfleetid(shipno);
            soshiphead.setIfleetid2(shipno);
            soshiphead.setVclicense(db.getCarnumber());
            soshiphead.setIdriverid(driverId);
            soshiphead.setDtarrive(db.getCreatetime());
            soshipheadMapper.updateByPrimaryKeySelective(soshiphead);
        }

        return soshiphead.getIlineid();
    }

    /**
     * 将运单明细保存到soshipline中
     * @param db
     * @param startCity
     * @param endCity
     * @param soshipheadId
     * @return
     */
    private void saveWayBillToSoshipLine(HYCWayBillDB db,Smcitymap startCity,Smcitymap endCity,Long soshipheadId,Hycwaybilldetail hycwaybilldetail,int size,Long iCustShipId) throws Exception{

        //获取得到订单的id
        Long iorderid2 = soorderMapper.getIlineidByOrderNo(hycwaybilldetail.getOrdercode());
        if(iorderid2 == null || "".equals(iorderid2)){
            LOGGER.error("未找到对应的订单"+hycwaybilldetail.getOrdercode());
            callOrderByHYCService.getOrderDetails(hycwaybilldetail.getOrdercode());
            iorderid2 = soorderMapper.getIlineidByOrderNo(hycwaybilldetail.getOrdercode());
        }

        //查询是否存在运单明细，如果不存在，则添加，存在则更新价格
        SoshiplineExample example = new SoshiplineExample();
        example.createCriteria().andIshipidEqualTo(soshipheadId).andIorderid2EqualTo(iorderid2);
        List<Soshipline> soshiplines = soshiplineMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(soshiplines)){
            Long ilineid = soshiplineMapper.getNextValID();
            Soshipline soshipline = new Soshipline();
            soshipline.setIlineid(ilineid);
            soshipline.setIshipid(soshipheadId);
            soshipline.setIstartcityid(startCity.getVccityid());
            soshipline.setVcstartcityname(startCity.getVccityname());
            soshipline.setIendcityid(endCity.getVccityid());
            soshipline.setVcendcityname(endCity.getVccityname());
            soshipline.setDcshipqty((short)1);
            soshipline.setIstartcityid2(startCity.getVccityid());
            soshipline.setVcstartcityname2(startCity.getVccityname());
            soshipline.setIendcityid2(endCity.getVccityid());
            soshipline.setVcendcityname2(endCity.getVccityname());
            soshipline.setDtcreatedate(db.getCreatetime());
            soshipline.setDtstartdate(db.getShipmentdate());
            soshipline.setDtoutdate(db.getShipmentdate());
            soshipline.setDtcomedate(db.getArrivedate());
            soshipline.setDcpaycost(hycwaybilldetail.getUnitcost());
            soshipline.setIflag(15L);
            soshipline.setIorderid(iorderid2);
            soshipline.setIorderid2(iorderid2);
            soshipline.setDtdate(new Date());
            soshipline.setIpaycosttype(1);

            //跟据运单对erp订单进行拆分
            Long iorderid = this.splitSoorderByShip(db,startCity,endCity,hycwaybilldetail,iorderid2);
            soshipline.setIorderid(iorderid);
            soshiplineMapper.saveWayBillDetailByHYC(soshipline);

            //SOCUSTSGIPORDER 新增客户订单与指令的关系
            this.saveSoCustShipOrder(db,iorderid2,ilineid,iCustShipId);
        }
        else{
            //如果存在更新价格
            Soshipline soshipline = soshiplines.get(0);
            soshipline.setDcpaycost(hycwaybilldetail.getUnitcost());
            soshiplineMapper.updateByExampleSelective(soshipline,example);
        }
    }


    /**
     * 新增客户订单与指令的关系
     * @param db
     * @param iOrderId
     * @param iShipLineId
     * @param iCustShipId
     */
    private void saveSoCustShipOrder(HYCWayBillDB db,Long iOrderId,Long iShipLineId,Long iCustShipId){
        SocustshiporderExample example = new SocustshiporderExample();
        example.createCriteria().andIcustshipidEqualTo(iCustShipId).andIshiplineidEqualTo(iShipLineId);
        int intCount= socustshiporderMapper.countByExample(example);
        if(intCount <=0 ){
            Long ilineid = socustshiporderMapper.getCustShipNextId();
            Socustshiporder socustshiporder = new Socustshiporder();
            socustshiporder.setIlineid(ilineid);
            socustshiporder.setIorderid(iOrderId);
            socustshiporder.setIshiplineid(iShipLineId);
            socustshiporder.setIcustshipid(iCustShipId);
            socustshiporder.setDcqty(1);
            socustshiporder.setDtregdate(db.getShipmentdate());
            socustshiporder.setVcuserno("system");
            socustshiporder.setDtreturndate(db.getArrivedate());
            socustshiporder.setItype(1);
            socustshiporder.setDcqty2(0);
            socustshiporder.setBreturn(1);
            socustshiporder.setVcreturnuserno("system");
            //判断是否是第一段(0:否,1:是)
            example = new SocustshiporderExample();
            example.createCriteria().andIcustshipidEqualTo(iCustShipId);
            intCount = socustshiporderMapper.countByExample(example);
            //如果不存在
            if(intCount <=0){
                socustshiporder.setIflag(1);
            }
            else{
                socustshiporder.setIflag(0);
            }
            socustshiporderMapper.insertCustShipByHYC(socustshiporder);
        }
    }

    /**
     * 新增客户运单号
     * @param db
     * @param vccustshipno
     * @param size
     */
    private Long saveSoCustomerShip(HYCWayBillDB db,String vccustshipno,Integer size){

        // 根据系统订单号的到客户运单号
        SocustomershipExample example = new SocustomershipExample();
        example.createCriteria().andVccustshipnoEqualTo(vccustshipno);
        List<Socustomership>  lists = socustomershipMapper.selectByExample(example);
        Long ilineid =0l;

        if(CollectionUtils.isEmpty(lists)){
            ilineid = socustomershipMapper.getCustomerNextId();
            Socustomership socustomership = new Socustomership();
            socustomership.setIlineid(ilineid);
            socustomership.setVccustshipno(vccustshipno);
            socustomership.setDtregdate(new Date());
            socustomership.setDcqty((long)size);
            socustomership.setDtshipprint(new Date());
            socustomership.setVcuserno("system");
            socustomership.setVcmemo("慧运车导入");
            socustomership.setDtshipreceive(db.getArrivedate());
            socustomership.setIflag(0);
            socustomershipMapper.saveCustomerByHYC(socustomership);
        }
        else{
            Socustomership socustomership = lists.get(0);
            ilineid = socustomership.getIlineid();
        }

        return ilineid;
    }

    /**
     * 跟据运单对erp订单进行拆分
     * @param db
     * @param startCity
     * @param endCity
     * @param hycwaybilldetail
     * @param iorderId
     * @return
     * @throws Exception
     */
    private Long splitSoorderByShip(HYCWayBillDB db,Smcitymap startCity, Smcitymap endCity, Hycwaybilldetail hycwaybilldetail,Long iorderId) throws  Exception{
        //获取订单信息
        Soorder soorder = soorderMapper.selectByPrimaryKey(iorderId);

        //获取拆分的订单编号
        //根据运单
        if(hycwaybilldetail.getServicedispatchtimes() == 1){
            //判断起运城市与终止城市是否与订单的一致
            if(startCity.getVccityname().equals(soorder.getVcstartcity()) && endCity.getVccityname().equals(soorder.getVccityname())){
                if("中联物流自有车队".equals(db.getCarriername()) || db.getCarrierid() == 151){
                    soorder.setIsdispatch((short)1);
                    soorder.setDcshipedqty((short)0);
                    soorder.setHycwaybillcode(hycwaybilldetail.getWaybillcode());
                }else{
                    soorder.setIsdispatch((short)0);
                    soorder.setDcshipedqty((short)1);
                }
                soorderMapper.updateDispatchByPrimaryKey(soorder);
                return iorderId;
            }
        }

        String vcorderNo = hycwaybilldetail.getServicedispatchtimes() + soorder.getVcorderno();

        //判断提车库是否存在
        Long getPointId = checkIntermediateService.judgeGetPointIsExist(soorder.getIcustomerid(),startCity.getVccityname(), db.getDepartprovincename());

        //获取订单的主键值
        Long ilineid = soorderMapper.getNextIlineid();

        soorder.setIlineid(ilineid);
        soorder.setIpid(iorderId);
        soorder.setIorderid(iorderId);
        soorder.setDcjsqty((short)0);
        soorder.setIdealerid((short)0);
        soorder.setDtcreatedate(new Date());
        soorder.setVcorderno(vcorderNo);
        soorder.setVcstartcity(db.getDepartcityname());
        soorder.setVccityname(db.getReceiptcityname());
        soorder.setDckilometer(BigDecimal.valueOf(1));
        soorder.setVcstartcity(startCity.getVccityname());
        soorder.setIgetpoint(getPointId);
        soorder.setVccityname(endCity.getVccityname());
        soorder.setIdestid(0);
        soorder.setDataresource("来源于慧运车导入");
        soorder.setDcshipedqty(Short.valueOf("1"));

        if("中联物流自有车队".equals(db.getCarriername()) || db.getCarrierid() == 151){
            soorder.setIsdispatch((short)1);
            soorder.setDcshipedqty((short)0);
            soorder.setHycwaybillcode(hycwaybilldetail.getWaybillcode());
        }else{
            soorder.setIsdispatch((short)0);
            soorder.setDcshipedqty((short)0);
        }

        SoorderExample example = new SoorderExample();
        example.createCriteria().andVcordernoEqualTo(vcorderNo);
        int intCount = soorderMapper.countByExample(example);

        if(intCount <= 0){
            soorderMapper.saveSoorderByHYC(soorder);
            return ilineid;
        }else{
            soorderMapper.updateSoorderByHYC(soorder);
            return soorder.getIlineid();
        }
    }

    @Override
    public void doSaveWaybillList() throws Exception {
        List<Hycwaybilllist> hycwaybilllistList = hycwaybilllistMapper.getAll();
        if(CollectionUtils.isNotEmpty(hycwaybilllistList)){
            for(Hycwaybilllist hycwaybilllist : hycwaybilllistList){
                String waybillcode = hycwaybilllist.getWaybillcode();

                hycwaybillMapper.clearWayBillByCode(waybillcode);
                hycwaybilldetailMapper.clearWayBillDetailByCode(waybillcode);
                Long ishipid = soshipheadMapper.getShipHeadIdByCode(waybillcode);

                //删除客户运单号
                //先取出指令明细
                if(!Objects.isNull(ishipid)) {
                    SoshiplineExample example = new SoshiplineExample();
                    example.createCriteria().andIshipidEqualTo(ishipid);
                    List<Soshipline> lists = soshiplineMapper.selectByExample(example);
                    if (!CollectionUtils.isEmpty(lists)) {
                        lists.forEach(soshipline -> {
                            Long ishiplineId = soshipline.getIlineid();
                            socustshiporderMapper.clearByIshiplineid(ishiplineId);
                        });
                    }

                    soshiplineMapper.clearByShipId(ishipid);
                    soshipheadMapper.clearByPrimaryKey(ishipid);
                }

                this.saveWayBillDetails(waybillcode);
            }
        }
    }
}
